#include <stdio.h>

#ifdef MAC_OS_X
    #include "GDAL/ogrsf_frmts.h"
    #include <GDAL/ogr_spatialref.h>
#else
    #include "ogrsf_frmts.h"
    #include <ogr_spatialref.h>
#endif


static OGRGeometry* createClipBox(double xmin, double ymin, double xmax, double ymax);
   
int main (int argc, char * const argv[]) {
    OGRRegisterAll();
    OGRDataSource *poDS;

    poDS = OGRSFDriverRegistrar::Open(argv[1], FALSE );
    if( poDS == NULL ) {
        printf( "Open failed.\n" );
        exit( 1 );
    }
    
    double xmin, ymin, xmax, ymax;
    xmin = 116.40014648437500;
    ymin = 39.90552253633076;
    xmax = 116.40563964843750;
    ymax = 39.90973623113919;

    
    OGRGeometry *poSpatialFilter = createClipBox(xmin, ymin, xmax, ymax);

    for(int iLayer = 0; iLayer < poDS->GetLayerCount(); ++iLayer) {
        OGRLayer *poLayer = poDS->GetLayer(iLayer);

        if(poLayer == NULL) {
            fprintf(stderr, "FAILURE: Couldn't fetch advertised layer %d!\n", iLayer);
            exit(1);
        }

        poLayer->SetSpatialFilter(poSpatialFilter);

        OGRFeature *poFeature;
        while (TRUE) {
            poFeature = poLayer->GetNextFeature();
            
            if (poFeature == NULL) {
                break;
            }

            for (int i = 0; i < poFeature->GetFieldCount(); ++i) {
                printf("%s : %s\n", poFeature->GetFieldDefnRef(i)->GetNameRef(), poFeature->GetFieldAsString(i));
            }
            printf("%s\n", poFeature->GetGeometryRef()->exportToJson());


            OGRFeature::DestroyFeature( poFeature );
        }
    }

//    OGRDataSource::DestroyDataSource(poDS);
    delete poDS;

    return 0;
}

static OGRGeometry* createClipBox(double xmin, double ymin, double xmax, double ymax) {
    OGRLinearRing oRing;
    oRing.addPoint(xmin, ymin);
    oRing.addPoint(xmin, ymax);
    oRing.addPoint(xmax, ymax);
    oRing.addPoint(xmax, ymin);
    oRing.addPoint(xmin, ymin);

    OGRGeometry *poSpatialFilter = new OGRPolygon();
    ((OGRPolygon *) poSpatialFilter)->addRing(&oRing);

    return poSpatialFilter;
}
